package com.jason.library.dsl

/**
 * @description: DSLMain
 *
 * @author ChenBaoyang
 * @date 2021/9/30 14:31
 */
object DSLMain {

    @JvmStatic
    fun main(args: Array<String>) {
        doLogin4()
    }

}

/**
 * 原始的适配方式
 */
fun doLogin1() {
    val operator = LoginOperator()
    operator.addCallBack(object : OnLoginCallback{
        override fun onSuccess(userId: String) {
            println("userId = $userId")
        }

        override fun onFailed(code: Int, message: String?) {
            println("code = $code, message = $message")
        }

        override fun onRobUser(changed: Boolean) {
            println("changed = $changed")
        }

    })
    operator.testLoginSuccess()
}

/**
 * 空适配模式
 */
fun doLogin2() {
    val operator = LoginOperator()
    operator.addCallBack(object : EmptyLoginCallBack() {
        override fun onSuccess(userId: String) {
            println("userId = $userId")
        }
    })
    operator.testLoginSuccess()
}

/**
 * 定义一个空类
 */
open class EmptyLoginCallBack : OnLoginCallback{
    override fun onSuccess(userId: String) {

    }

    override fun onFailed(code: Int, message: String?) {

    }

    override fun onRobUser(changed: Boolean) {

    }
}

/**
 * 高阶函数
 */
fun doLogin3() {
    val operator = LoginOperator()
    operator.addCallBackClosure(
        success = {
            println("userId = $it")
        }
    )
    operator.testLoginSuccess()
}

/**
 * 定义一个内联拓展函数
 */
inline fun LoginOperator.addCallBackClosure(
    crossinline success: (String) -> Unit = {},
    crossinline failed: (Int, String?) -> Unit = {Int, String -> },
    crossinline robUser: (Boolean) -> Unit = {}
){
    addCallBack(object : OnLoginCallback{
        override fun onSuccess(userId: String) {
            success.invoke(userId)
        }

        override fun onFailed(code: Int, message: String?) {
            failed.invoke(code, message)
        }

        override fun onRobUser(changed: Boolean) {
            robUser.invoke(changed)
        }
    })
}

/**
 * DSL的写法
 */
fun doLogin4() {
    val operator = LoginOperator()
    operator.addCallBackDsl {
        onSuccess {
            println("userId = $it")
        }
    }
    operator.testLoginSuccess()
}

fun LoginOperator.addCallBackDsl(init1: LoginCallbackDsl.() -> Unit) {
    val callback = LoginCallbackDsl()
    callback.init1()
    addCallBack(callback)
}


/**
 * 定义一个新类，通过定义dsl方法来实现
 *
 * @property success Function1<String, Unit>?
 * @property failed Function2<Int, String?, Unit>?
 * @property robUser Function1<Boolean, Unit>?
 */
class LoginCallbackDsl : OnLoginCallback {

    var success: ((String) ->Unit)? = null

    var failed: ((Int, String?) -> Unit)? = null

    var robUser: ((Boolean) -> Unit)? = null

    /**
     * 定义DSL方法
     */
    fun onSuccess(method: ((String) -> Unit)?) {
        success = method
    }

    fun onFailed(method: ((Int, String?) -> Unit)?) {
        failed = method
    }

    fun onRobUser(method: ((Boolean) -> Unit)?) {
        robUser = method
    }


    override fun onSuccess(userId: String) {
        success?.invoke(userId)
    }

    override fun onFailed(code: Int, message: String?) {
        failed?.invoke(code, message)
    }

    override fun onRobUser(changed: Boolean) {
        robUser?.invoke(changed)
    }

}



/************************************公共条件***********************************/

/**
 * 登录操作类
 *
 * @property callback OnLoginCallback?
 */
class LoginOperator{
    private var callback: OnLoginCallback? = null

    fun addCallBack(callback: OnLoginCallback?){
        this.callback = callback
    }

    fun testLoginSuccess(){
        callback?.let {
            it.onSuccess("123123-${(0..100).random()}")
        }
    }
}

/**
 * 登录回调接口
 */
interface OnLoginCallback{

    fun onSuccess(userId: String)

    fun onFailed(code: Int, message: String?)

    fun onRobUser(changed: Boolean)
}